"""MCP GitHub服务器实现"""

import asyncio
import os
from typing import Any, Dict, List, Optional
from mcp.server.fastmcp import FastMCP
from github import Github
import aiohttp
import json

# 创建MCP服务器
mcp = FastMCP("GitHub")

# GitHub客户端
github_client = None
github_token = None

def initialize_github():
    """初始化GitHub客户端"""
    global github_client, github_token
    github_token = os.getenv("GITHUB_TOKEN")
    if github_token:
        github_client = Github(github_token)
        print(f"🔧 [MCP GitHub] GitHub客户端初始化成功")
    else:
        print(f"⚠️ [MCP GitHub] 未找到GITHUB_TOKEN环境变量")

@mcp.tool()
def search_repositories(query: str, language: str = None, sort: str = "stars", order: str = "desc", per_page: int = 10) -> Dict[str, Any]:
    """搜索GitHub仓库
    
    Args:
        query: 搜索查询
        language: 编程语言过滤
        sort: 排序方式 (stars, forks, updated)
        order: 排序顺序 (asc, desc)
        per_page: 每页结果数量
    """
    print(f"🔍 [MCP GitHub] 搜索仓库: '{query}'")
    
    if not github_client:
        return {"error": "GitHub客户端未初始化"}
    
    try:
        # 构建搜索查询
        search_query = query
        if language:
            search_query += f" language:{language}"
        
        # 搜索仓库
        repositories = github_client.search_repositories(
            query=search_query,
            sort=sort,
            order=order
        )
        
        results = []
        count = 0
        for repo in repositories:
            if count >= per_page:
                break
                
            results.append({
                "name": repo.name,
                "full_name": repo.full_name,
                "description": repo.description or "",
                "url": repo.html_url,
                "stars": repo.stargazers_count,
                "forks": repo.forks_count,
                "language": repo.language,
                "updated_at": repo.updated_at.isoformat() if repo.updated_at else None,
                "topics": repo.get_topics() if hasattr(repo, 'get_topics') else []
            })
            count += 1
        
        print(f"✅ [MCP GitHub] 找到 {len(results)} 个仓库")
        return {
            "repositories": results,
            "total_count": repositories.totalCount,
            "query": search_query
        }
        
    except Exception as e:
        print(f"❌ [MCP GitHub] 搜索仓库失败: {str(e)}")
        return {"error": f"搜索失败: {str(e)}"}

@mcp.tool()
def search_code(query: str, language: str = None, filename: str = None, repo: str = None, per_page: int = 10) -> Dict[str, Any]:
    """搜索GitHub代码
    
    Args:
        query: 搜索查询
        language: 编程语言过滤
        filename: 文件名过滤
        repo: 仓库过滤 (格式: owner/repo)
        per_page: 每页结果数量
    """
    print(f"🔍 [MCP GitHub] 搜索代码: '{query}'")
    
    if not github_client:
        return {"error": "GitHub客户端未初始化"}
    
    try:
        # 构建搜索查询
        search_query = query
        if language:
            search_query += f" language:{language}"
        if filename:
            search_query += f" filename:{filename}"
        if repo:
            search_query += f" repo:{repo}"
        
        # 搜索代码
        code_results = github_client.search_code(query=search_query)
        
        results = []
        count = 0
        for code in code_results:
            if count >= per_page:
                break
                
            # 获取文件内容片段
            try:
                content = code.decoded_content.decode('utf-8')[:500] + "..." if len(code.decoded_content) > 500 else code.decoded_content.decode('utf-8')
            except:
                content = "无法解码文件内容"
            
            results.append({
                "name": code.name,
                "path": code.path,
                "repository": code.repository.full_name,
                "url": code.html_url,
                "content_snippet": content,
                "size": code.size,
                "sha": code.sha
            })
            count += 1
        
        print(f"✅ [MCP GitHub] 找到 {len(results)} 个代码文件")
        return {
            "code_files": results,
            "total_count": code_results.totalCount,
            "query": search_query
        }
        
    except Exception as e:
        print(f"❌ [MCP GitHub] 搜索代码失败: {str(e)}")
        return {"error": f"搜索失败: {str(e)}"}

@mcp.tool()
def search_issues(query: str, repo: str = None, state: str = "open", sort: str = "updated", order: str = "desc", per_page: int = 10) -> Dict[str, Any]:
    """搜索GitHub Issues
    
    Args:
        query: 搜索查询
        repo: 仓库过滤 (格式: owner/repo)
        state: Issue状态 (open, closed, all)
        sort: 排序方式 (created, updated, comments)
        order: 排序顺序 (asc, desc)
        per_page: 每页结果数量
    """
    print(f"🔍 [MCP GitHub] 搜索Issues: '{query}'")
    
    if not github_client:
        return {"error": "GitHub客户端未初始化"}
    
    try:
        # 构建搜索查询
        search_query = f"{query} type:issue"
        if repo:
            search_query += f" repo:{repo}"
        if state != "all":
            search_query += f" state:{state}"
        
        # 搜索Issues
        issues = github_client.search_issues(
            query=search_query,
            sort=sort,
            order=order
        )
        
        results = []
        count = 0
        for issue in issues:
            if count >= per_page:
                break
                
            results.append({
                "number": issue.number,
                "title": issue.title,
                "body": (issue.body[:300] + "...") if issue.body and len(issue.body) > 300 else (issue.body or ""),
                "state": issue.state,
                "url": issue.html_url,
                "repository": issue.repository.full_name if hasattr(issue, 'repository') else None,
                "user": issue.user.login if issue.user else None,
                "created_at": issue.created_at.isoformat() if issue.created_at else None,
                "updated_at": issue.updated_at.isoformat() if issue.updated_at else None,
                "comments": issue.comments,
                "labels": [label.name for label in issue.labels] if hasattr(issue, 'labels') else []
            })
            count += 1
        
        print(f"✅ [MCP GitHub] 找到 {len(results)} 个Issues")
        return {
            "issues": results,
            "total_count": issues.totalCount,
            "query": search_query
        }
        
    except Exception as e:
        print(f"❌ [MCP GitHub] 搜索Issues失败: {str(e)}")
        return {"error": f"搜索失败: {str(e)}"}

@mcp.tool()
def get_repository_info(owner: str, repo: str) -> Dict[str, Any]:
    """获取仓库详细信息
    
    Args:
        owner: 仓库所有者
        repo: 仓库名称
    """
    print(f"🔍 [MCP GitHub] 获取仓库信息: {owner}/{repo}")
    
    if not github_client:
        return {"error": "GitHub客户端未初始化"}
    
    try:
        repository = github_client.get_repo(f"{owner}/{repo}")
        
        # 获取语言统计
        languages = repository.get_languages()
        
        # 获取最近的提交
        commits = list(repository.get_commits()[:5])
        recent_commits = []
        for commit in commits:
            recent_commits.append({
                "sha": commit.sha[:7],
                "message": commit.commit.message.split('\n')[0],
                "author": commit.commit.author.name if commit.commit.author else None,
                "date": commit.commit.author.date.isoformat() if commit.commit.author and commit.commit.author.date else None
            })
        
        result = {
            "name": repository.name,
            "full_name": repository.full_name,
            "description": repository.description or "",
            "url": repository.html_url,
            "clone_url": repository.clone_url,
            "ssh_url": repository.ssh_url,
            "stars": repository.stargazers_count,
            "forks": repository.forks_count,
            "watchers": repository.watchers_count,
            "open_issues": repository.open_issues_count,
            "language": repository.language,
            "languages": languages,
            "size": repository.size,
            "default_branch": repository.default_branch,
            "created_at": repository.created_at.isoformat() if repository.created_at else None,
            "updated_at": repository.updated_at.isoformat() if repository.updated_at else None,
            "pushed_at": repository.pushed_at.isoformat() if repository.pushed_at else None,
            "topics": repository.get_topics() if hasattr(repository, 'get_topics') else [],
            "license": repository.license.name if repository.license else None,
            "recent_commits": recent_commits,
            "has_issues": repository.has_issues,
            "has_projects": repository.has_projects,
            "has_wiki": repository.has_wiki,
            "archived": repository.archived,
            "disabled": repository.disabled,
            "private": repository.private
        }
        
        print(f"✅ [MCP GitHub] 获取仓库信息成功")
        return result
        
    except Exception as e:
        print(f"❌ [MCP GitHub] 获取仓库信息失败: {str(e)}")
        return {"error": f"获取仓库信息失败: {str(e)}"}

@mcp.tool()
def get_file_content(owner: str, repo: str, path: str, ref: str = None) -> Dict[str, Any]:
    """获取文件内容
    
    Args:
        owner: 仓库所有者
        repo: 仓库名称
        path: 文件路径
        ref: 分支或提交SHA (默认为默认分支)
    """
    print(f"🔍 [MCP GitHub] 获取文件内容: {owner}/{repo}/{path}")
    
    if not github_client:
        return {"error": "GitHub客户端未初始化"}
    
    try:
        repository = github_client.get_repo(f"{owner}/{repo}")
        
        if ref:
            file_content = repository.get_contents(path, ref=ref)
        else:
            file_content = repository.get_contents(path)
        
        # 解码文件内容
        try:
            content = file_content.decoded_content.decode('utf-8')
        except UnicodeDecodeError:
            content = "二进制文件，无法显示内容"
        
        result = {
            "name": file_content.name,
            "path": file_content.path,
            "content": content,
            "size": file_content.size,
            "sha": file_content.sha,
            "url": file_content.html_url,
            "download_url": file_content.download_url,
            "type": file_content.type,
            "encoding": file_content.encoding
        }
        
        print(f"✅ [MCP GitHub] 获取文件内容成功")
        return result
        
    except Exception as e:
        print(f"❌ [MCP GitHub] 获取文件内容失败: {str(e)}")
        return {"error": f"获取文件内容失败: {str(e)}"}

if __name__ == "__main__":
    # 初始化GitHub客户端
    initialize_github()
    
    # 运行MCP服务器
    print("🚀 [MCP GitHub] 启动GitHub MCP服务器...")
    mcp.run()